﻿using Repository;
using System;
using System.Collections.Generic;
using Util;
using System.Linq;
using Microsoft.Extensions.Logging;
using Domain.Base;
using Domain.Entity;
using Cache;
using DtoFw.Result;
using DtoFw.Query;
using DtoFw;
using DtoFw.Base;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using DtoFw.Enum;
using Domain.Entity.Aprove;

namespace Service
{
    public class MainHomeService
    {
        private readonly MainUserRepository rep_mainUser;
        private readonly MainRoleRepository rep_mainRole;
        private readonly MainUserMapRoleRepository rep_mainUserMap;
        private readonly MainRoleMapMenuRepository rep_mainRoleMapMenu;
        private readonly MainMenuRepository rep_mainMenu;
        private readonly MainLogRepository rep_log;
        private readonly MainDicRepository _mainDicRepository;
        private readonly MainConfigRepository _mainConfigRepository;
        private readonly MainImgRepository _mainImgRepository;
        private readonly MainOrganRepository _mainOrganRepository;
        private readonly CasePhysicalEvidenceTransfereRepository _casePhysicalEvidenceTransfereRepository;
        private readonly NotificationRepository _notificationRepository;
        private readonly CaseAttachFileRepository _attachFileRepository;
        private readonly IHostingEnvironment _hostingEnvironment;
        private ILogger<MainHomeService> _logger;
        public MainHomeService(MainUserRepository mainUser, MainRoleRepository mainRole, MainLogRepository mainLogRepository, MainDicRepository mainDicRepository, MainConfigRepository mainConfigRepository,
            MainUserMapRoleRepository mainUserMap, MainRoleMapMenuRepository mainRoleMapMenu, MainMenuRepository mainMenu, MainImgRepository mainImgRepository,
            IHostingEnvironment hostingEnvironment, MainOrganRepository mainOrganRepository, CasePhysicalEvidenceTransfereRepository casePhysicalEvidenceTransfereRepository,
            NotificationRepository notificationRepository,
            ILogger<MainHomeService> logger, CaseAttachFileRepository attachFileRepository)
        {
            rep_mainUser = mainUser;
            rep_mainRole = mainRole;
            rep_mainUserMap = mainUserMap;
            rep_mainRoleMapMenu = mainRoleMapMenu;
            rep_mainMenu = mainMenu;
            rep_log = mainLogRepository;
            _mainDicRepository = mainDicRepository;
            _mainConfigRepository = mainConfigRepository;
            _mainImgRepository = mainImgRepository;
            _hostingEnvironment = hostingEnvironment;
            _mainOrganRepository = mainOrganRepository;
            _casePhysicalEvidenceTransfereRepository = casePhysicalEvidenceTransfereRepository;
            _notificationRepository = notificationRepository;
            _logger = logger;
            _attachFileRepository = attachFileRepository;
        }
        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="entity"></param>
        public void AddLog(MinLogEntity entity)
        {
            rep_log.Insert(entity);
        }
        /// <summary>
        /// 常规配置保存
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public BaseResult SaveConfigSetting(ConfigSettingDto dto)
        {
            _mainConfigRepository.GetDb().BeginTran();
            _mainConfigRepository.Delete(new BaseOperate(),
                  t => t.Where(m => m.Class == dto.Class));
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = dto.Class;
            mainConfigEntity.ClassName = dto.ClassName;
            mainConfigEntity.CategoryCode = "";
            mainConfigEntity.CategoryName = "";
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Content = Newtonsoft.Json.JsonConvert.SerializeObject(dto);
            if (_mainConfigRepository.Insert(mainConfigEntity) > 0)
            {
                _mainConfigRepository.GetDb().CommitTran();
                return BaseResult.Succeed();
            }
            return BaseResult.Failure("硬件配置保存成功");
        }
        /// <summary>
        /// 获取预警配置
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<ConfigRequestDto> GetWarningConfig(string classCode, string categoryCode)
        {
            var entity = _mainConfigRepository.GetDb()
                 .Queryable<MainConfigEntity>()
                 .First(x => !x.IsDeleted && x.CategoryCode == categoryCode && x.Class == classCode);
            if (entity == null)
                return BaseGenericResult<ConfigRequestDto>.Failure(new ConfigRequestDto(), "未获取到预警配置，请重新保存");
            var resp = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigRequestDto>(entity.Content);
            return BaseGenericResult<ConfigRequestDto>.Succeed(resp);
        }
        /// <summary>
        /// 保存预警配置
        /// </summary>
        /// <returns></returns>
        public BaseResult SaveWarningConfig(ConfigRequestDto dto)
        {
            if (dto == null)
                return BaseResult.Failure("参数错误");
            var r1 = _mainConfigRepository.Delete(new BaseOperate(),
                    t => t.Where(m => m.CategoryCode == EnumClass.WarnConfig && m.Class == EnumClass.WarnConfig)) > 0;
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = EnumClass.WarnConfig;
            mainConfigEntity.ClassName = "预警设置";
            mainConfigEntity.CategoryCode = EnumClass.WarnConfig;
            mainConfigEntity.CategoryName = "预警设置";
            mainConfigEntity.Content = Newtonsoft.Json.JsonConvert.SerializeObject(dto);
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Status = true;
            var r2 = _mainConfigRepository.Insert(mainConfigEntity) > 0;
            if (r2)
                return BaseResult.Succeed();
            return BaseResult.Failure("操作失败");
        }

        #region 系统配置
        /// <summary>
        /// 保存系统配置
        /// </summary>
        /// <returns></returns>
        public BaseResult SaveSystemConfig(SystemConfigDto dto)
        {
            if (dto == null)
                return BaseResult.Failure("参数错误");
            var r1 = _mainConfigRepository.Delete(new BaseOperate(),
                    t => t.Where(m => m.CategoryCode == EnumClass.SysConfig && m.Class == EnumClass.SysConfig)) > 0;
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = EnumClass.SysConfig;
            mainConfigEntity.ClassName = "系统配置";
            mainConfigEntity.CategoryCode = EnumClass.SysConfig;
            mainConfigEntity.CategoryName = "系统配置";
            mainConfigEntity.Content = Newtonsoft.Json.JsonConvert.SerializeObject(dto);
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Status = true;
            var r2 = _mainConfigRepository.Insert(mainConfigEntity) > 0;
            if (r2)
                return BaseResult.Succeed();
            return BaseResult.Failure("操作失败");
        }
        /// <summary>
        /// 查询系统配置
        /// </summary>
        public BaseGenericResult<SystemConfigDto> QuerySystemConfigDto()
        {
            SystemConfigDto t = new SystemConfigDto();
            var r1 = _mainConfigRepository.Query(new BaseQuery(), t => t.Where(m => m.CategoryCode == EnumClass.SysConfig && m.Class == EnumClass.SysConfig)).First();
            if (r1 != null)
            {
                t = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemConfigDto>(r1.Content);
            }
            return new BaseGenericResult<SystemConfigDto>() { Success = true, Code = EnumReturnCode.Success, Data = t };
        }

        #endregion

        #region 硬件配置

        /// <summary>
        /// 保存系统配置
        /// </summary>
        /// <returns></returns>
        public BaseResult SaveHardwareConfig(HandwareConfigDto dto)
        {
            if (dto == null)
                return BaseResult.Failure("参数错误");
            var r1 = _mainConfigRepository.Delete(new BaseOperate(),
                    t => t.Where(m => m.CategoryCode == EnumClass.HardwareConfig && m.Class == EnumClass.HardwareConfig)) > 0;
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = EnumClass.HardwareConfig;
            mainConfigEntity.ClassName = "硬件配置";
            mainConfigEntity.CategoryCode = EnumClass.HardwareConfig;
            mainConfigEntity.CategoryName = "硬件配置";
            mainConfigEntity.Content = dto.configJson;
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Status = true;
            var r2 = _mainConfigRepository.Insert(mainConfigEntity) > 0;
            if (r2)
                return BaseResult.Succeed();
            return BaseResult.Failure("操作失败");
        }
        /// <summary>
        /// 查询系统配置
        /// </summary>
        public BaseGenericResult<string> QueryHardwareDto()
        {
            var ret = "[]";
            var r1 = _mainConfigRepository.Query(new BaseQuery(), t => t.Where(m => m.CategoryCode == EnumClass.HardwareConfig && m.Class == EnumClass.HardwareConfig)).First();
            if (r1 != null)
            {
                ret = r1.Content;
            }
            return new BaseGenericResult<string>() { Success = true, Code = EnumReturnCode.Success, Data = ret };
        }

        #endregion 硬件配置

        #region 流程配置

        /// <summary>
        /// 保存流程配置
        /// </summary>
        /// <returns></returns>
        public BaseResult SaveFlowConfig(HandwareConfigDto dto)
        {
            if (dto == null)
                return BaseResult.Failure("参数错误");
            var r1 = _mainConfigRepository.Delete(new BaseOperate(),
                    t => t.Where(m => m.CategoryCode == EnumClass.FlowConfig && m.Class == EnumClass.FlowConfig)) > 0;
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = EnumClass.FlowConfig;
            mainConfigEntity.ClassName = "流程配置";
            mainConfigEntity.CategoryCode = EnumClass.FlowConfig;
            mainConfigEntity.CategoryName = "流程配置";
            mainConfigEntity.Content = dto.configJson;
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Status = true;
            var r2 = _mainConfigRepository.Insert(mainConfigEntity) > 0;
            if (r2)
                return BaseResult.Succeed();
            return BaseResult.Failure("操作失败");
        }
        /// <summary>
        /// 查询流程配置
        /// </summary>
        public BaseGenericResult<string> QueryFlowConfig()
        {
            var ret = "[]";
            var r1 = _mainConfigRepository.Query(new BaseQuery(), t => t.Where(m => m.CategoryCode == EnumClass.FlowConfig && m.Class == EnumClass.FlowConfig)).First();
            if (r1 != null)
            {
                ret = r1.Content;
            }
            return new BaseGenericResult<string>() { Success = true, Code = EnumReturnCode.Success, Data = ret };
        }
        #endregion 流程配置

        #region 备份配置

        /// <summary>
        /// 保存流程配置
        /// </summary>
        /// <returns></returns>
        public BaseResult SaveBakConfig(HandwareConfigDto dto)
        {
            if (dto == null)
                return BaseResult.Failure("参数错误");
            var r1 = _mainConfigRepository.Delete(new BaseOperate(),
                    t => t.Where(m => m.CategoryCode == EnumClass.DbBakConfig && m.Class == EnumClass.DbBakConfig)) > 0;
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            mainConfigEntity.Class = EnumClass.DbBakConfig;
            mainConfigEntity.ClassName = "数据库配置";
            mainConfigEntity.CategoryCode = EnumClass.DbBakConfig;
            mainConfigEntity.CategoryName = "数据库配置";
            mainConfigEntity.Content = dto.configJson;
            mainConfigEntity.Creator = dto.UserName;
            mainConfigEntity.CreatorId = dto.UserId;
            mainConfigEntity.Status = true;
            var r2 = _mainConfigRepository.Insert(mainConfigEntity) > 0;
            if (r2)
                return BaseResult.Succeed();
            return BaseResult.Failure("操作失败");
        }
        /// <summary>
        /// 查询流程配置
        /// </summary>
        public BaseGenericResult<string> QueryBakConfig()
        {
            var ret = "[]";
            var r1 = _mainConfigRepository.Query(new BaseQuery(), t => t.Where(m => m.CategoryCode == EnumClass.DbBakConfig && m.Class == EnumClass.DbBakConfig)).First();
            if (r1 != null)
            {
                ret = r1.Content;
            }
            return new BaseGenericResult<string>() { Success = true, Code = EnumReturnCode.Success, Data = ret };
        }

        #endregion 备份配置

        private bool SetWarnConfig(MainConfigEntity mainConfigEntity,
            bool status,
            EarlyWarningConfigEnum @enum,
            string json)
        {
            var CategoryCode = @enum.ToString();
            if (_mainConfigRepository.Delete(new BaseOperate(),
                t => t.Where(m => m.CategoryCode == CategoryCode && m.CategoryCode == "WaraingConfig")) < 1)
                return true;
            mainConfigEntity.CategoryCode = CategoryCode;
            mainConfigEntity.CategoryName = EnumHelper.GetEnumDescription(EarlyWarningConfigEnum.Tag);
            mainConfigEntity.Status = status;
            mainConfigEntity.Content = json;
            return _mainConfigRepository.Insert(mainConfigEntity) > 0;
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public List<MainDicEntity> GetDics(string code)
        {
            List<MainDicEntity> list = GlobalData.Cache.Get<List<MainDicEntity>>(code);
            if (list != null && list.Count > 0)
                return list;
            List<MainDicEntity> reflis = new List<MainDicEntity>();
            var entity = _mainDicRepository.Get(new BaseQuery(),
                 t => t.Where(m => m.Code == code));
            var all = _mainDicRepository.Query(new BaseQuery())?.ToList();
            RecursionDic(entity?.Id, all, ref reflis);
            GlobalData.Cache.Set(code, Newtonsoft.Json.JsonConvert.SerializeObject(reflis));
            return reflis;
        }
        private void RecursionDic(long? id, List<MainDicEntity> all,
            ref List<MainDicEntity> reflist)
        {
            var _all = all.FindAll(x => x.ParentId == id);
            foreach (var item in _all)
            {
                if (!item.ChildNode)
                {
                    reflist.Add(item);
                    RecursionDic(item.Id, all, ref reflist);
                }
                else
                {
                    reflist.Add(item);
                }
            }
        }
        /// <summary>
        /// 获取系统操作日志
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<Pager<LogResult>> GetLogs(LogQuery query)
        {
            int total = 0;
            var list = rep_log.Query(new BaseQuery(),
                t => t.Where(x => !x.IsDeleted)
                .WhereIF(!string.IsNullOrWhiteSpace(query.Method), x => x.Method == query.Method))
                .WhereIF(!string.IsNullOrWhiteSpace(query.ModuleName), x => x.Module.Contains(query.ModuleName))
                .WhereIF(!string.IsNullOrWhiteSpace(query.ActionName), x => x.Action.Contains(query.ActionName))
                .WhereIF(!string.IsNullOrWhiteSpace(query.User), x => x.Creator.Contains(query.User))
                .WhereIF((query.StartDate.HasValue && query.EndDate.HasValue), x => (x.CreateTime > query.StartDate && x.CreateTime < query.EndDate))
                .WhereIF(!string.IsNullOrWhiteSpace(query.Content), x => x.RequestBody.Contains(query.Content))
                .ToPageList(query.Page, query.PageSize, ref total);
            BaseGenericResult<Pager<LogResult>> baseGeneric = new BaseGenericResult<Pager<LogResult>>();
            baseGeneric.Data = new Pager<LogResult>();
            baseGeneric.Data.Data = AutoMapperExtension.MapTo<MinLogEntity, LogResult>(list);
            baseGeneric.Data.TotalCount = total;
            return baseGeneric;
        }
        /// <summary>
        /// 获取登录用户信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<MainUserLoginResult> GetLoginUserInfo(long? id)
        {
            var userinfo = rep_mainUser.Get(new BaseQuery(),
                  t => t.Where(m => m.Id == id));
            var usermaprole = rep_mainUserMap.Get(new BaseQuery(),
                  t => t.Where(m => m.UserId == userinfo.Id));
            var userOrgan = _mainOrganRepository.Get(new BaseQuery(),
                t => t.Where(m => m.Id == userinfo.OrgId));
            var role = rep_mainRole.Get(new BaseQuery() { Id = usermaprole.RoleId });
            BaseGenericResult<MainUserLoginResult> baseResult = new BaseGenericResult<MainUserLoginResult>();
            baseResult.Data = new MainUserLoginResult();
            baseResult.Data.Id = userinfo.Id;
            baseResult.Data.Name = userinfo.Name;
            baseResult.Data.RoleName = role.Name;
            baseResult.Data.RoleId = role.Id;
            baseResult.Data.OrganName = userOrgan.CName;
            baseResult.Data.roleMenus = QueryVueRoleMenus(new MenuQuery() { UserId = userinfo.Id, MenuType = 0, RoleId = role.Id, Page = 1, PageSize = 100, MenuId = 0 })?.Data;
            return baseResult;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<MainUserLoginInfo> Login(MainUserLoginQuery query)
        {
            var userinfo = rep_mainUser.Get(new BaseQuery(),
                  t => t.Where(m => m.UserNo == query.username));
            if (userinfo == null)
                return new BaseGenericResult<MainUserLoginInfo>() { Success = false, Msg = "用户账号不存在" };
            string pwd = SecurityHelper.GetPwd(query.password, userinfo.Salt);
            if (!userinfo.Pwd.Equals(pwd))
                return new BaseGenericResult<MainUserLoginInfo>() { Success = false, Msg = "用户密码错误" };
            var usermaprole = rep_mainUserMap.Get(new BaseQuery(), t => t.Where(m => m.UserId == userinfo.Id));
            if (usermaprole == null)
                return new BaseGenericResult<MainUserLoginInfo>() { Success = false, Msg = "未分配用户角色" };
            var role = rep_mainRole.Get(new BaseQuery() { Id = usermaprole.RoleId });
            if (role == null)
                return new BaseGenericResult<MainUserLoginInfo>() { Success = false, Msg = "角色不存在" };
            BaseGenericResult<MainUserLoginInfo> baseResult = new BaseGenericResult<MainUserLoginInfo>();
            baseResult.Data = new MainUserLoginInfo();
            baseResult.Data.Id = userinfo.Id;
            baseResult.Data.RoleId = role.Id;
            baseResult.Data.UserName = userinfo.Name;
            baseResult.Data.OrganId = userinfo.OrgId;
            baseResult.Data.Phone = userinfo.Phone;
            baseResult.Data.OrganName = _mainOrganRepository
                .GetDb().Queryable<MainOrganEntity>().First(x => x.Id == userinfo.OrgId && !x.IsDeleted)?.Name;
            baseResult.Data.Token = SetToken(userinfo, userinfo.Id, role.Id, TokenTypeEnum.AccessToken);
            baseResult.Data.RefreshToken = SetToken(userinfo, userinfo.Id, role.Id, TokenTypeEnum.RefreshToken);
            baseResult.Data.notification = new Notification();

            var lastMessage = GetLastMessage(userinfo.Id);

            baseResult.Data.notification.NotificationNum = lastMessage.Item1;
            baseResult.Data.notification.NotificationContent = lastMessage.Item2;
            return baseResult;
        }
        private Tuple<int, string> GetLastMessage(long UserId)
        {
            //获取未读消息数
            long notificationId = _notificationRepository.GetDb().Queryable<NoticeLogEntity>().Where(x => x.UserId == UserId).Max(x => x.NotificationId);
            int count = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(x => x.IsDeleted == false && x.IsHandle != 0).Count(x => x.Id > notificationId);
            var lastMessage = _notificationRepository.Query(new BaseQuery(),
                x => x.Where(m => m.Id == notificationId))?.First();
            return new Tuple<int, string>(count,
                lastMessage?.Describe);
        }
        /// <summary>
        /// 获取token
        /// </summary>
        /// <param name="mainUser"></param>
        /// <returns></returns>
        private string SetToken(MainUserEntity mainUser,
            long memberId, long roleId, TokenTypeEnum typeEnum)
        {
            var organ = _mainOrganRepository.Get(new BaseQuery(), t => t.Where(m => m.Id == mainUser.OrgId));
            TokenData tokenData = new TokenData();
            tokenData.UserName = mainUser.Name;
            tokenData.UserId = mainUser.Id;
            tokenData.RoleId = roleId;
            tokenData.UserNo = mainUser.UserNo;
            tokenData.OrganId = mainUser.OrgId;
            tokenData.OrganName = organ?.CName;
            tokenData.Mobile = mainUser.Phone;
            tokenData.ComNo = organ?.ComNo;
            tokenData.DeptId = mainUser.OrgDeptId;
            return TokenHelper.CreateToken(tokenData, typeEnum);
        }
        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<List<RoleMenuResult>> QueryVueRoleMenus(MenuQuery query)
        {
            List<RoleMenuResult> childMenuResults = new List<RoleMenuResult>();
            List<MainRoleMapMenuEntity> roleMapMenus = rep_mainRoleMapMenu.Query(new BaseQuery(), m => m.Where(t => t.RoleId == query.RoleId))?.ToList();
            List<RoleMenuResult> menuResults = new List<RoleMenuResult>();
            Pager<RoleMenuResult> menuInfoResults = this.rep_mainMenu.QuerPageMenuList(query);
            menuInfoResults.Data.ForEach(t =>
            {
                if (roleMapMenus.Count(x => x.MenuId == t.Id) > 0)
                {
                    menuResults.Add(new RoleMenuResult()
                    {
                        Id = t.Id,
                        Level = t.Level,
                        ParentId = t.ParentId,
                        Name = t.Name,
                        Path = t.Path,
                        Sort = t.Sort,
                        Component = t.Component,
                        Title = t.Title,
                        Icon = t.Icon,
                        IsLink = t.IsLink,
                        IsHide = t.IsHide,
                        IsKeepAlive = t.IsKeepAlive,
                        IsAffix = t.IsAffix,
                        LinkPath = t.LinkPath,
                        Auth = t.Auth
                    });
                }
            });
            var menus0 = menuResults.Where(t => t.Level == 0)?.ToList();
            menus0.ForEach(t =>
            {
                RoleMenuResult roleMenuResult = new RoleMenuResult()
                {
                    Id = t.Id,
                    Level = t.Level,
                    ParentId = t.ParentId,
                    Name = t.Name,
                    Path = t.Path,
                    Sort = t.Sort,
                    Component = t.Component,
                    Meta = new Meta()
                    {
                        Title = t.Title,
                        Icon = t.Icon,
                        IsLink = t.IsLink,
                        IsHide = t.IsHide,
                        IsKeepAlive = t.IsKeepAlive,
                        IsAffix = t.IsAffix,
                        LinkPath = t.LinkPath,
                        Component = t.Component,
                        Auth = Newtonsoft.Json.JsonConvert.DeserializeObject<List<String>>(t.Auth)
                    }
                };
                roleMenuResult.Children = new List<RoleMenuResult>();
                var menus1 = menuResults.Where(p => p.ParentId == t.Id)?.OrderBy(t => t.Sort)?.ToList();
                menus1.ForEach(x =>
                {
                    var roleMenuResult1 = new RoleMenuResult()
                    {
                        Id = x.Id,
                        Level = x.Level,
                        ParentId = x.ParentId,
                        Name = x.Name,
                        Path = x.Path,
                        Sort = x.Sort,
                        Component = x.Component,
                        Children = new List<RoleMenuResult>(),
                        Meta = new Meta()
                        {
                            Title = x.Title,
                            Icon = x.Icon,
                            IsLink = x.IsLink,
                            IsHide = x.IsHide,
                            IsKeepAlive = x.IsKeepAlive,
                            IsAffix = x.IsAffix,
                            LinkPath = x.LinkPath,
                            Component = x.Component,
                            Auth = string.IsNullOrWhiteSpace(x.Auth) ? new List<string>() { "admin" } : Newtonsoft.Json.JsonConvert.DeserializeObject<List<String>>(x.Auth)
                        }
                    };
                    var menus2 = menuResults.Where(p => p.ParentId == x.Id)?.OrderBy(t => t.Sort)?.ToList();
                    menus2.ForEach(z =>
                    {
                        roleMenuResult1.Children.Add(new RoleMenuResult()
                        {
                            Id = z.Id,
                            Level = z.Level,
                            ParentId = z.ParentId,
                            Name = z.Name,
                            Path = z.Path,
                            Sort = z.Sort,
                            Component = z.Component,
                            Children = new List<RoleMenuResult>(),
                            Meta = new Meta()
                            {
                                Title = z.Title,
                                Icon = z.Icon,
                                IsLink = z.IsLink,
                                IsHide = z.IsHide,
                                IsKeepAlive = z.IsKeepAlive,
                                IsAffix = z.IsAffix,
                                LinkPath = z.LinkPath,
                                Component = z.Component,
                                Auth = string.IsNullOrWhiteSpace(z.Auth) ? new List<string>() { "admin" } : Newtonsoft.Json.JsonConvert.DeserializeObject<List<String>>(z.Auth)
                            }
                        });
                    });
                    roleMenuResult.Children.Add(roleMenuResult1);
                });
                childMenuResults.Add(roleMenuResult);
            });
            BaseGenericResult<List<RoleMenuResult>> baseResult = new BaseGenericResult<List<RoleMenuResult>>();
            baseResult.Data = childMenuResults?.OrderBy(t => t.Sort)?.ToList();
            return baseResult;
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name = "requestDto" ></ param >
        /// < returns ></ returns >
        public BaseGenericResult<Pager<MenuInfoResult>> GetPager(MenuQuery query)
        {
            BaseGenericResult<Pager<MenuInfoResult>> baseResult = new BaseGenericResult<Pager<MenuInfoResult>>();
            baseResult.Data = this.rep_mainMenu.QuerPageList(query);
            return baseResult;
        }
        /// <summary>
        /// 根据级别查询菜单列表
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public BaseGenericResult<List<MenuLevelResult>> QueryToLevel(int level)
        {
            BaseGenericResult<List<MenuLevelResult>> baseResult = new BaseGenericResult<List<MenuLevelResult>>();
            baseResult.Data = new List<MenuLevelResult>();
            List<MainMenuEntity> menus = this.rep_mainMenu.Query(new BaseQuery(), m => m.Where(t => t.Level == level
                    && t.Type == 0))?.ToList();
            menus.ForEach(t =>
            {
                baseResult.Data.Add(new MenuLevelResult()
                {
                    Id = t.Id,
                    MenuName = t.Name
                });
            });
            return baseResult;
        }
        /// <summary>
        /// 新增菜单
        /// </summary>
        /// <param name="query">请求对象</param>
        /// <returns></returns>
        public BaseResult Post(MenuInfo info)
        {
            MainMenuEntity menuInfo = rep_mainMenu.Get(new BaseQuery(), m => m.Where(t => t.Name == info.Name && !t.IsDeleted));
            if (menuInfo != null)
                return BaseResult.Failure("添加失败，该菜单名已存在");
            menuInfo = Util.AutoMapperExtension.MapTo<MenuInfo, MainMenuEntity>(info, menuInfo);
            menuInfo.CreatorId = info.UserId;
            menuInfo.CreateTime = DateTime.Now;
            menuInfo.Creator = info.UserName;
            if (rep_mainMenu.Save(menuInfo)?.Id < 1)
                return BaseResult.Failure("添加菜单失败");
            return BaseResult.Succeed();
        }
        /// <summary>
        /// 菜单编辑
        /// </summary>
        /// <param name="query">请求对象</param>
        /// <returns></returns>
        public BaseResult Put(MenuEditInfo info)
        {
            MainMenuEntity menuInfo = rep_mainMenu.Get(new BaseQuery() { Id = info.Id });
            menuInfo = Util.AutoMapperExtension.MapTo<MenuEditInfo, MainMenuEntity>(info, menuInfo);
            menuInfo.ModifyerId = info.UserId;
            menuInfo.ModifyerTime = DateTime.Now;
            menuInfo.Modifyer = info.UserName;
            menuInfo.IsLink = info.IsLink == "false" ? "" : info.IsLink;
            menuInfo.LinkPath = info.IsLink == "false" ? "" : info.LinkPath;
            if (rep_mainMenu.Save(menuInfo)?.Id < 1)
                return BaseResult.Failure("添加菜单失败");
            return BaseResult.Succeed();
        }
        /// <summary>
        /// 移除菜单
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public BaseResult Delete(DeleteDto query)
        {
            BaseResult responseDto = new BaseResult();
            bool isChilds = false;
            List<MainMenuEntity> menus = this.rep_mainMenu.Query(new BaseQuery())?.ToList();
            foreach (var item in query.Ids)
            {
                isChilds = menus.Count(t => t.ParentId == item) > 0;
                if (isChilds)
                    break;
            }
            if (isChilds)
            {
                responseDto.Success = false;
                responseDto.Msg = "待删除的父级菜单下还有未删除的子菜单，请先删除子菜单";
                return responseDto;
            }
            int result = rep_mainMenu.DeleteBatch(new BaseOperate()
            {
                Ids = query.Ids,
                Modifyer = query.UserName,
                ModifyerId = query.UserId
            });
            if (result > 0)
                return responseDto;
            responseDto.Success = false;
            responseDto.Msg = "移除失败，内部错误";
            return responseDto;
        }
        /// <summary>
        /// 根据Id查询菜单
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public BaseGenericResult<MenuEditInfo> QueryModel(long Id)
        {
            BaseGenericResult<MenuEditInfo> baseResult = new BaseGenericResult<MenuEditInfo>();
            MainMenuEntity menuInfo = this.rep_mainMenu.Get(new BaseQuery() { Id = Id });
            baseResult.Data = Util.AutoMapperExtension.MapTo<MainMenuEntity, MenuEditInfo>(menuInfo);
            return baseResult;
        }
        /// <summary>
        /// 图片上传
        /// </summary>
        /// <param name="ty"></param>
        /// <param name="id"></param>
        /// <param name="fileInfo"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public BaseGenericResult<string> UploadImg(long userId, string ty,
            string id, string no, FileInfo fileInfo, Byte[] byts)
        {
            long _id = 0;
            int _ty = 0;
            Int64.TryParse(id, out _id);
            Int32.TryParse(ty, out _ty);
            UpadteImgStatus(_ty, _id, no);
            string path = _hostingEnvironment.ContentRootPath;
            string fileName = string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddHHssfff"), fileInfo.Extension);
            File.WriteAllBytes($"{path}//img//{fileName}", byts);
            string url = $"{GlobalData.EvidenceInfo.BaseImgUrl}{fileName}";
            if (_mainImgRepository.Insert(new MainImgEntity()
            {
                RelevanceId = Convert.ToInt64(id),
                Name = fileInfo.Name,
                Type = Convert.ToInt32(ty),
                Url = url,
                Size = byts.Length,
                Suffix = fileInfo.Extension.ToUpper(),
                RelevanceNo = no
            }) > 0 && UpdateSignImgs(userId, _ty, url))
                return BaseGenericResult<string>.Succeed(url);
            return BaseGenericResult<string>.Succeed("");
        }

        /// 图片上传
        /// </summary>
        /// <param name="ty"></param>
        /// <param name="id"></param>
        /// <param name="fileInfo"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public BaseGenericResult<string> UploadCaseAttachFile(TokenData user, string caseid, string evidenceId, FileInfo fileInfo, Byte[] byts)
        {
            string path = _hostingEnvironment.ContentRootPath.Replace("\\", "/");
            var url = $"/img/case_attach/case_{caseid}/";
            if (!System.IO.Directory.Exists(path + url))
            {
                System.IO.Directory.CreateDirectory(path + url);
            }
            url = $"{url}{DateTime.Now.ToString("yyyyMMddHHssfff")}{fileInfo.Extension}";
            File.WriteAllBytes(path + url, byts);
            var e = new CaseAttachFileEntity()
            {
                CaseId = Convert.ToInt64(caseid),
                EvidenceId = Convert.ToInt64(evidenceId),
                Title = fileInfo.Name,
                Path = $"{GlobalData.EvidenceInfo.BaseImgUrl.Replace("/img/", "")}{url}",
                Size = byts.Length,
                Ext = fileInfo.Extension.ToUpper(),
                CreateTime = DateTime.Now,
                Creator = user.UserName,
                CreatorId = user.UserId,
                Modifyer = user.UserName,
                ModifyerId = user.UserId,
                ModifyerTime = DateTime.Now,
            };
            _attachFileRepository.Insert(e);
            if (e.Id > 0)
            {
                _attachFileRepository.eviRef.Insert(new CaseAttachFileEvidenceEntity()
                {
                    attachId = e.Id,
                    Creator = e.Creator,
                    CreateTime = e.CreateTime,
                    CreatorId = e.CreatorId,
                    evidenceId = e.EvidenceId,
                    caseId = e.CaseId,
                    Modifyer = e.Modifyer,
                    ModifyerId = e.ModifyerId,
                    ModifyerTime = e.ModifyerTime,
                });
                return BaseGenericResult<string>.Succeed(url);
            }
            return BaseGenericResult<string>.Succeed("");
        }

        /// <summary>
        /// 附件上传 拍照
        /// </summary>
        /// <param name="user"></param>
        /// <param name="caseid"></param>
        /// <param name="evidenceId"></param>
        /// <param name="fileInfo"></param>
        /// <param name="byts"></param>
        /// <returns></returns>
        public BaseGenericResult<string> UploadCaseAttachFile(TokenData user, string caseid, string evidenceId, string url)
        {
            var e = new CaseAttachFileEntity()
            {
                CaseId = Convert.ToInt64(caseid),
                EvidenceId = Convert.ToInt64(evidenceId),
                Title = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
                Path = url,
                Size = 3000,
                Ext = "jpg",
                CreateTime = DateTime.Now,
                Creator = user.UserName,
                CreatorId = user.UserId,
                Modifyer = user.UserName,
                ModifyerId = user.UserId,
                ModifyerTime = DateTime.Now,
            };
            _attachFileRepository.Insert(e);
            if (e.Id > 0)
            {
                _attachFileRepository.eviRef.Insert(new CaseAttachFileEvidenceEntity()
                {
                    attachId = e.Id,
                    Creator = e.Creator,
                    CreateTime = e.CreateTime,
                    CreatorId = e.CreatorId,
                    evidenceId = e.EvidenceId,
                    caseId = e.CaseId,
                    Modifyer = e.Modifyer,
                    ModifyerId = e.ModifyerId,
                    ModifyerTime = e.ModifyerTime,
                });
                return BaseGenericResult<string>.Succeed(url);
            }
            return BaseGenericResult<string>.Succeed("");
        }



        /// <summary>
        /// 图片上传
        /// </summary>
        /// <param name="ty"></param>
        /// <param name="id"></param>
        /// <param name="fileInfo"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public BaseGenericResult<string> UploadImgOneOnly(FileInfo fileInfo, Byte[] byts)
        {
            string path = _hostingEnvironment.ContentRootPath;
            string fileName = string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddHHssfff"), fileInfo.Extension);
            File.WriteAllBytes($"{path}//img//{fileName}", byts);
            string url = $"{GlobalData.EvidenceInfo.BaseImgUrl}{fileName}";
            return BaseGenericResult<string>.Succeed(url);
        }


        /// <summary>
        /// 图片上传
        /// </summary>
        /// <param name="ty"></param>
        /// <param name="id"></param>
        /// <param name="fileInfo"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public BaseResult UploadBase64Imgs(long userId, int ty, long id,
            string no, List<Byte[]> fileByts)
        {
            UpadteImgStatus(ty, id, no);
            string url = "";
            List<MainImgEntity> mainImgEntities = new List<MainImgEntity>();
            fileByts.ForEach(byts =>
            {
                string path = _hostingEnvironment.ContentRootPath;
                string fileName = string.Format("{0}.JPG", DateTime.Now.ToString("yyyyMMddHHssfff"));
                File.WriteAllBytes($"{path}//img//{fileName}", byts);
                url = $"{GlobalData.EvidenceInfo.BaseImgUrl}{fileName}";
                mainImgEntities.Add(new MainImgEntity()
                {
                    RelevanceId = id,
                    Name = fileName,
                    Type = ty,
                    Url = url,
                    Size = byts.Length,
                    Suffix = ".JPG",
                    RelevanceNo = no
                });
            });
            if (_mainImgRepository.InsertBatch(mainImgEntities) > 0 && UpdateSignImgs(userId, ty, url))
                return BaseResult.Succeed();
            return BaseResult.Failure("上传失败");
        }
        /// <summary>
        /// 更新保管人签名
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ty"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private bool UpdateSignImgs(long userId, int ty,
            string url)
        {
            if (ty == 6)
                return rep_mainUser.GetDb().Updateable<MainUserEntity>().SetColumns(x => new MainUserEntity() { Extend1 = url })
                    .Where(x => x.Id == userId && !x.IsDeleted).ExecuteCommand() > 0;
            return true;
        }
        /// <summary>
        /// 确保出库/入库签名只存在一个
        /// </summary>
        /// <param name="ty"></param>
        /// <param name="id"></param>
        /// <param name="no"></param>
        private void UpadteImgStatus(int ty, long id, string no)
        {
            if (ty == 5 || ty == 4 || ty == 6)
            {
                var linq = _mainImgRepository.GetDb().Updateable<MainImgEntity>()
                    .SetColumns(x => new MainImgEntity() { IsDeleted = true })
                    .Where(x => !x.IsDeleted && ty == x.Type);
                if (string.IsNullOrWhiteSpace(no) && id > 0)
                {
                    linq.Where(x => x.RelevanceId == id).ExecuteCommand();
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(no))
                        linq.Where(x => x.RelevanceNo == no).ExecuteCommand();
                }
            }
        }
        private List<BaseImgRespDto> GetImgsExt(string relevance, long relevanceId,
            int type = 0)
        {
            var transfere = _casePhysicalEvidenceTransfereRepository.GetDb()
                        .Queryable<CasePhysicalEvidenceTransfereEntity>()
                        .Where(x => !x.IsDeleted)
                        .WhereIF(relevanceId > 0, x => x.Id == relevanceId)
                        .WhereIF(!string.IsNullOrWhiteSpace(relevance) && relevanceId < 1, x => x.DeliveryNo == relevance)?.First();
            var userImages = rep_mainUser.GetDb().
                 Queryable<MainUserEntity>().Where(x => !x.IsDeleted && x.Id == transfere.CreatorId && !string.IsNullOrWhiteSpace(x.Extend1))?
                 .Select(x => new BaseImgRespDto()
                 {
                     Id = x.Id,
                     Name = x.Name,
                     Url = x.Extend1,
                     Type = 6
                 })?.ToList();
            var urls = userImages.Select(x => x.Url)?.ToList();
            var imgs = _mainImgRepository.GetDb().Queryable<MainImgEntity>().Where(x => !x.IsDeleted && !urls.Contains(x.Url) && !string.IsNullOrWhiteSpace(x.Url))
              .WhereIF(relevanceId > 0, x => x.RelevanceId == relevanceId)
              .WhereIF(relevanceId <= 0, x => x.RelevanceNo == relevance)
              .WhereIF(type == 10, x => x.Type == 4 || x.Type == 6)
              .WhereIF(type == 11, x => x.Type == 5 || x.Type == 6)
              .Select(x => new BaseImgRespDto()
              {
                  Id = x.Id,
                  Url = x.Url,
                  Name = x.Name,
                  Type = x.Type
              })?.ToList();
            imgs.AddRange(userImages);
            return imgs;
        }
        /// <summary>
        /// 获取关联图片列表
        /// </summary>
        /// <param name="relevanceId"></param>
        /// <returns></returns>
        public BaseGenericResult<List<BaseImgRespDto>> GetImgs(string relevance,
            int type = 0)
        {
            long relevanceId = 0;
            if (string.IsNullOrWhiteSpace(relevance))
                return BaseGenericResult<List<BaseImgRespDto>>.Succeed(new List<BaseImgRespDto>());
            Int64.TryParse(relevance, out relevanceId);
            if (type == 10 || type == 11)
            {
                var templist = GetImgsExt(relevance, relevanceId, type);
                return BaseGenericResult<List<BaseImgRespDto>>.Succeed(templist);
            }
            var list = _mainImgRepository.GetDb()
                .Queryable<MainImgEntity>()
                .Where(x => !x.IsDeleted)
                .WhereIF(relevanceId > 0, x => x.RelevanceId == relevanceId)
                .WhereIF(relevanceId <= 0, x => x.RelevanceNo == relevance)
                .WhereIF(type > 0, x => x.Type == type)
                .Select(x => new BaseImgRespDto()
                {
                    Type = x.Type,
                    Id = x.Id,
                    Url = x.Url,
                    Name = x.Name
                })?.ToList();
            return BaseGenericResult<List<BaseImgRespDto>>.Succeed(list);
        }

        /// <summary>
        /// 入库前检测照片和文书
        /// </summary>
        /// <param name="wzs"></param>
        /// <returns></returns>
        public BaseGenericResult<bool> CheckImgs(List<BaseImgRespDto> wzs)
        {
            foreach (var item in wzs)
            {

                //查询照片是否存在
                var list = _mainImgRepository.GetDb()
               .Queryable<MainImgEntity>()
               .Where(x => !x.IsDeleted && x.Type == 1)
               .Where(x => x.RelevanceNo == item.wzNo)
               .Count();

                if (list <= 0)
                    return BaseGenericResult<bool>.Succeed(false);

                //查询文书是否存在
                //var files = _mainImgRepository.GetDb()
                //         .Queryable<CaseAttachFileEvidenceEntity>()
                //         .Where(x => !x.IsDeleted)
                //         .Where(x => x.evidenceId == item.Id)
                //         .Count();

                //if (files <= 0)
                //    return BaseGenericResult<bool>.Succeed(false);
            }

            return BaseGenericResult<bool>.Succeed(true);
        }


        /// <summary>
        /// 删除图片关联列表
        /// </summary>
        /// <param name="relevanceId"></param>
        /// <returns></returns>
        public BaseResult DeleteImg(DeleteSingleDto deleteSingleDto)
        {
            int result = 0;
            if (deleteSingleDto.Id > 0)
            {
                result = _mainImgRepository.Delete(new BaseOperate() { Id = deleteSingleDto.Id });
            }
            else
            {
                var list = _mainImgRepository.GetDb()
                      .Queryable<MainImgEntity>()
                      .Where(x => !x.IsDeleted && x.RelevanceNo == deleteSingleDto.No)?.ToList();
                list = list.Select(x =>
                {
                    x.IsDeleted = true;
                    return x;
                })?.ToList();
                result = _mainImgRepository.GetDb().Updateable<MainImgEntity>(list).ExecuteCommand();
            }
            if (result > 0)
            {
                return BaseResult.Succeed();
            }
            return BaseResult.Failure("删除失败");
        }
        /// <summary>
        /// Token过期刷新
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public BaseGenericResult<string> RefreshToken(string refreshToken)
        {
            string accessToken = string.Empty;
            var principal = TokenHelper.GetPrincipalFromAccessToken(refreshToken);
            if (principal != null)
            {
                var id = principal.Claims.FirstOrDefault(c => c.Type == "userId")?.Value;
                if (!string.IsNullOrEmpty(id))
                {
                    long _id = Convert.ToInt64(id);
                    if (_id > 0)
                    {
                        var user = rep_mainUser.Get(new BaseQuery() { Id = _id });
                        if (user != null)
                        {
                            var userRole = rep_mainUserMap.Get(new BaseQuery(),
                                 t => t.Where(m => m.UserId == user.Id));
                            accessToken = TokenHelper.RefreshToken(principal, new TokenData()
                            {
                                UserNo = user.UserNo,
                                UserName = user.Name,
                                UserId = user.Id,
                                RoleId = userRole.RoleId
                            });
                            GlobalData.Cache.Set(refreshToken, accessToken, GlobalData.JwtConfig.ExpiresMinutes * 60 - 10);
                        }
                    }
                }
            }
            return BaseGenericResult<string>.Succeed(accessToken);
        }

        public BaseResult WebScoketSend(WebScoketReqDto reqDto)
        {
            var reult = WebSocketModel.SendWarning(reqDto);
            return BaseResult.Succeed();
        }
    }
}
